﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Xml;
using System.Diagnostics;
using System.IO;
using Microsoft.Win32;

namespace CFScript.Tasks
{
    /// <summary>
    /// TODO: Update summary.
    /// </summary>
    public class RegistrySet : Task
    {
        public RegistrySet()
        {
            this.name = "<registrySet>";
            this.parameterNames = new string[] { "key", "name", "value", "type" };
            this.parameterExpandable = new bool[] { true, true, true, true };
            this.parameterRequired = new bool[] { true, true, true, true };
            this.parameters = new Dictionary<string, Parameter>();

            Debug.Assert(this.parameterNames.Length == this.parameterRequired.Length &&
                         this.parameterRequired.Length == this.parameterRequired.Length);
        }

        public override InstructionResult Execute(CFScript context)
        {
            InstructionResult result = new InstructionResult();
            result.ExecutedInstruction = this;

            string key = this.parameters["key"].GetValue(context);
            string name = this.parameters["name"].GetValue(context);
            string value = this.parameters["value"].GetValue(context);
            string type = this.parameters["type"].GetValue(context);

            // Default RegistryValueKind
            RegistryValueKind rvk = RegistryValueKind.String;

            switch (type.ToLower())
            {
                case "binary":
                    rvk = RegistryValueKind.Binary;
                    break;
                case "dword":
                    rvk = RegistryValueKind.DWord;
                    break;
                case "expandstring":
                    rvk = RegistryValueKind.ExpandString;
                    break;
                case "multristring":
                    rvk = RegistryValueKind.MultiString;
                    break;
                case "qword":
                    rvk = RegistryValueKind.QWord;
                    break;
                case "string":
                    rvk = RegistryValueKind.QWord;
                    break;
                case "unknown":
                    rvk = RegistryValueKind.Unknown;
                    break;
            }
            
            try
            {
                RegistryKey rk = Registry.LocalMachine.CreateSubKey(key);
                rk.SetValue(name, value, rvk);

                result.Code = ResultCode.OK;
            }
            catch (Exception ex)
            {
                result.Code = ResultCode.ERROR;
                result.Message = ex.Message;
            }

            result.BreakExecution = result.Code == ResultCode.ERROR && this.options.OnError == OnErrorAction.BREAK;

            return result;
        }
    }
}
